package sys

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 菜单相关接口
*******************************************************************************/
import (
	"permissions/api/cache"
	"permissions/model"

	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/gin-gonic/gin"
)

/*
 * 描述: 菜单列表
 * 路由: /menu/list
 * 方法: GET
 *********************************************************************/
type MenuList struct {
	Name  string       `form:"name" binding:"omitempty,max=64"`   // 权限名称
	Type  model.EPower `form:"type" binding:"omitempty"`          // 菜单类型(1:菜单;2:功能;3:数据)
	Match string       `form:"match" binding:"omitempty,max=128"` // 权限匹配项(完全匹配)
	State int          `form:"state" binding:"omitempty"`         // 状态(1:正常;2:失效)
}

func (this *MenuList) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	items, err := (&model.Power{
		Name:   this.Name,
		Type:   this.Type,
		CMatch: this.Match,
		State:  this.State,
	}).Find()
	if err != nil {
		return htp.RespDBErr("", err)
	}
	return htp.RespOK("", &struct {
		List []model.Power `json:"list"`
	}{items})
}

/*
 * 描述: 菜单树表
 * 路由: /menu/tree
 * 方法: GET
 *********************************************************************/
type MenuTree struct{}

func (this *MenuTree) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	items, err := (&model.Power{}).FindTree()
	if err != nil {
		return htp.RespDBErr("", err)
	}
	return htp.RespOK("", &struct {
		List []model.MenuLable `json:"list"`
	}{items})
}

/*
 * 描述: 新增菜单
 * 路由: /menu/add
 * 方法: POST
 *********************************************************************/
const ( // 错误码
	ECMAD_ParentNotFound htp.ECode = iota + 1 // 上级菜单不存在
)

type MenuAdd struct {
	ParentId int64        `form:"parentid" json:"parentid" binding:"omitempty"`         // 父Id
	Icon     string       `form:"icon" json:"icon" binding:"omitempty"`                 // 图标
	Name     string       `form:"name" json:"name" binding:"required,max=64"`           // 权限名称
	Type     model.EPower `form:"type" json:"type" binding:"required"`                  // 菜单类型(1:菜单;2:功能;3:数据)
	Match    string       `form:"match" json:"match" binding:"required,max=128"`        // 权限匹配项
	Comp     string       `form:"comp" json:"comp" binding:"omitempty,max=64"`          // 组件[菜单类型]
	UrlPath  string       `form:"url_path" json:"url_path" binding:"omitempty,max=128"` // 地址栏路径[菜单类型]
	Order    int          `form:"order" json:"order" binding:"omitempty"`               // 排序值
	State    int          `form:"state" json:"state" binding:"required"`                // 状态(1:正常;2:失效)
	Remark   string       `form:"remark" json:"remark" binding:"omitempty,max=128"`     // 备注
}

func (this *MenuAdd) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	p := &model.Power{Id: this.ParentId}
	if this.ParentId != 0 {
		if has, err := p.Load(); !has || err != nil {
			return htp.RespErr(ECMAD_ParentNotFound, "上级菜单不存在", err)
		}
	}

	m := model.Power{
		ParentId: this.ParentId,
		NodePath: model.NodePath(p.NodePath, p.Id),
		Icon:     this.Icon,
		Name:     this.Name,
		Type:     this.Type,
		Match:    this.Match,
		Comp:     this.Comp,
		UrlPath:  this.UrlPath,
		Tntyp:    model.ETreeNode_Leaf,
		Order:    this.Order,
		State:    this.State,
		Remark:   this.Remark,
	}
	if _, err := m.Create(); err != nil {
		return htp.RespDBErr("", err)
	}

	// 把父节点的Tntyp更新为Base
	if p.Tntyp == model.ETreeNode_Leaf {
		if _, err := (&model.Power{Tntyp: model.ETreeNode_Base}).Update(p.Id); err != nil {
			return htp.RespDBErr("更新父级用户组类型失败", err)
		}
	}
	return htp.RespOK("", &struct {
		Id int64 `json:"id"` // 权限Id
	}{m.Id})
}

/*
 * 描述: 编辑菜单
 * 路由: /menu/upd
 * 方法: POST
 *********************************************************************/

type MenuUpd struct {
	Id      int64        `form:"id" json:"id" binding:"required"`                      // 权限Id
	Icon    string       `form:"icon" json:"icon" binding:"omitempty"`                 // 图标
	Name    string       `form:"name" json:"name" binding:"required,max=64"`           // 权限名称
	Type    model.EPower `form:"type" json:"type" binding:"required"`                  // 菜单类型(1:菜单;2:功能;3:数据)
	Match   string       `form:"match" json:"match" binding:"required,max=128"`        // 权限匹配项
	Comp    string       `form:"comp" json:"comp" binding:"omitempty,max=64"`          // 组件[菜单类型]
	UrlPath string       `form:"url_path" json:"url_path" binding:"omitempty,max=128"` // 地址栏路径[菜单类型]
	Order   int          `form:"order" json:"order" binding:"omitempty"`               // 排序值
	State   int          `form:"state" json:"state" binding:"required"`                // 状态(1:正常;2:失效)
	Remark  string       `form:"remark" json:"remark" binding:"omitempty,max=128"`     // 备注
}

func (this *MenuUpd) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	mOld := model.Power{Id: this.Id}
	if has, err := mOld.Load(); !has || err != nil {
		return htp.RespDBErr("此菜单不存在", err)
	}

	mNew := model.Power{
		Id:      this.Id,
		Icon:    this.Icon,
		Name:    this.Name,
		Type:    this.Type,
		Match:   this.Match,
		Comp:    this.Comp,
		UrlPath: this.UrlPath,
		Order:   this.Order,
		State:   this.State,
		Remark:  this.Remark,
	}
	// 更新记录, 允许后面的几个字段被重置为默认值
	if _, err := mNew.Update(this.Id, "icon", "order", "remark"); err != nil {
		return htp.RespDBErr("", err)
	}

	util.Goroutine("HandRouteRoles", func() { // 更新路由角色缓存
		if mOld.Match == mNew.Match {
			return
		}
		if err := cache.HandRouteRoles([]int64{this.Id}, true); err != nil {
			util.Error("MenuDel.HandUserRoles err:%v", err)
		}
		if err := cache.HandRouteRoles([]int64{this.Id}, false); err != nil {
			util.Error("MenuDel.HandUserRoles err:%v", err)
		}
	})
	return htp.RespOK("", nil)
}

/*
 * 描述: 删除菜单
 * 路由: /menu/del
 * 方法: POST
 *********************************************************************/

type MenuDel struct {
	Id int64 `form:"id" json:"id" binding:"required"` // 权限Id
}

func (this *MenuDel) Handle(c *gin.Context) htp.Response {
	//user := comm.CurrUser(c)

	eff, err := (&model.Power{}).Delete(this.Id)
	if err != nil {
		return htp.RespDBErr("", err)
	}
	if eff == 0 {
		return htp.RespErr(htp.CodeTargetNotFound, "此菜单不存在", nil)
	}

	if _, err := (&model.RolePower{}).Delete(0, this.Id); err != nil {
		return htp.RespDBErr("", err)
	}

	util.Goroutine("HandRouteRoles", func() { // 更新路由角色缓存
		if err := cache.HandRouteRoles([]int64{this.Id}, true); err != nil {
			util.Error("MenuDel.HandUserRoles err:%v", err)
		}
	})
	return htp.RespOK("", nil)
}
